package com.fjnu.dao.impl;

import com.fjnu.dao.ArticleDao;
import com.fjnu.domain.dto.ArticleConditionDto;
import com.fjnu.domain.entity.Article;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Repository
public class ArticleDaoImpl implements ArticleDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int insert(Article article) {
        if (article == null || article.getUserId() == null || article.getTitle() == null ||
                article.getContent() == null || article.getCategoryId() == null ||
                article.getTitle().trim().isEmpty() || article.getContent().trim().isEmpty()) {
            return 0;
        }

        String sql = "INSERT INTO tb_article(user_id, title, content, status, description, " +
                "category_id, create_time, update_time, support, oppose, recommended, is_top, cover_img) " +
                "VALUES(?, ?, ?, ?, ?, ?, NOW(), NOW(), ?, ?, ?, ?, ?)";
        return jdbcTemplate.update(sql, article.getUserId(), article.getTitle(),
                article.getContent(), article.getStatus(), article.getDescription(),
                article.getCategoryId(),
                article.getSupport(), article.getOppose(), article.getRecommended(),
                article.getIsTop(), article.getCoverImg());
    }

    @Override
    public int updateContent(Integer id, String newContent) {
        if (id == null || newContent == null || newContent.trim().isEmpty()) {
            return 0;
        }
        String sql = "UPDATE tb_article SET content = ?, update_time = NOW() WHERE id = ?";
        return jdbcTemplate.update(sql, newContent, id);
    }

    @Override
    public int updateTitle(Integer id, String newTitle) {
        if (id == null || newTitle == null || newTitle.trim().isEmpty()) {
            return 0;
        }
        String sql = "UPDATE tb_article SET title = ?, update_time = NOW() WHERE id = ?";
        return jdbcTemplate.update(sql, newTitle, id);
    }

    @Override
    public int updateByCondition(Integer id, ArticleConditionDto articleCondition) {
        if (id == null || articleCondition == null) {
            return 0;
        }

        StringBuilder sql = new StringBuilder("UPDATE tb_article SET update_time = NOW()");
        List<Object> params = new ArrayList<>();

        if (articleCondition.getTitle() != null && !articleCondition.getTitle().trim().isEmpty()) {
            sql.append(", title = ?");
            params.add(articleCondition.getTitle());
        }
        if (articleCondition.getContent() != null && !articleCondition.getContent().trim().isEmpty()) {
            sql.append(", content = ?");
            params.add(articleCondition.getContent());
        }
        if (articleCondition.getStatus() != null) {
            sql.append(", status = ?");
            params.add(articleCondition.getStatus());
        }
        if (articleCondition.getDescription() != null && !articleCondition.getDescription().trim().isEmpty()) {
            sql.append(", description = ?");
            params.add(articleCondition.getDescription());
        }
        if (articleCondition.getCategoryId() != null) {
            sql.append(", category_id = ?");
            params.add(articleCondition.getCategoryId());
        }

        if (params.isEmpty()) {
            return 0;
        }

        sql.append(" WHERE id = ?");
        params.add(id);

        return jdbcTemplate.update(sql.toString(), params.toArray());
    }

    @Override
    public int updateStatus(Integer id, Integer newStatus) {
        if (id == null || newStatus == null || (newStatus != 0 && newStatus != 1)) {
            return 0;
        }
        String sql = "UPDATE tb_article SET status = ?, update_time = NOW() WHERE id = ?";
        return jdbcTemplate.update(sql, newStatus, id);
    }

    @Override
    public int batchUpdateStatus(List<Integer> ids, Integer newStatus) {
        if (ids == null || ids.isEmpty() || newStatus == null || (newStatus != 0 && newStatus != 1)) {
            return 0;
        }

        String sql = "UPDATE tb_article SET status = ?, update_time = NOW() WHERE id = ?";
        List<Object[]> batchArgs = new ArrayList<>();
        for (Integer id : ids) {
            batchArgs.add(new Object[]{newStatus, id});
        }

        int[] results = jdbcTemplate.batchUpdate(sql, batchArgs);
        return (int) Arrays.stream(results).filter(result -> result > 0).count();
    }

    @Override
    public int deleteById(Integer id) {
        if (id == null) {
            return 0;
        }
        String sql = "DELETE FROM tb_article WHERE id = ?";
        return jdbcTemplate.update(sql, id);
    }

    @Override
    public List<Article> selectByUserId(Integer userId) {
        if (userId == null) {
            return null;
        }
        String sql = "SELECT * FROM tb_article WHERE user_id = ? ORDER BY create_time DESC";
        List<Article> articles = jdbcTemplate.query(sql,
                new BeanPropertyRowMapper<>(Article.class), userId);
        return articles.isEmpty() ? null : articles;
    }

    @Override
    public List<Article> selectByKeyWord(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return null;
        }
        String sql = "SELECT * FROM tb_article WHERE title LIKE ? OR content LIKE ? ORDER BY create_time DESC";
        String likeKeyword = "%" + keyword + "%";
        List<Article> articles = jdbcTemplate.query(sql,
                new BeanPropertyRowMapper<>(Article.class), likeKeyword, likeKeyword);
        return articles.isEmpty() ? null : articles;
    }

    @Override
    public List<Article> selectByTimePeriod(Date startTime, Date endTime) {
        StringBuilder sql = new StringBuilder("SELECT * FROM tb_article WHERE 1=1");
        List<Object> params = new ArrayList<>();

        if (startTime != null) {
            sql.append(" AND create_time >= ?");
            params.add(startTime);
        }
        if (endTime != null) {
            sql.append(" AND create_time <= ?");
            params.add(endTime);
        }

        sql.append(" ORDER BY create_time DESC");
        List<Article> articles = jdbcTemplate.query(sql.toString(),
                new BeanPropertyRowMapper<>(Article.class), params.toArray());
        return articles.isEmpty() ? null : articles;
    }

    @Override
    public List<Article> selectByTag(Integer tagId) {
        if (tagId == null) {
            return null;
        }
        String sql = "SELECT a.* FROM tb_article a " +
                "INNER JOIN tb_article_tag at ON a.id = at.article_id " +
                "WHERE at.tag_id = ? ORDER BY a.create_time DESC";
        List<Article> articles = jdbcTemplate.query(sql,
                new BeanPropertyRowMapper<>(Article.class), tagId);
        return articles.isEmpty() ? null : articles;
    }

    @Override
    public List<Article> selectByCategory(Integer categoryId) {
        if (categoryId == null) {
            return null;
        }
        String sql = "SELECT * FROM tb_article WHERE category_id = ? ORDER BY create_time DESC";
        List<Article> articles = jdbcTemplate.query(sql,
                new BeanPropertyRowMapper<>(Article.class), categoryId);
        return articles.isEmpty() ? null : articles;
    }

    @Override
    public Article selectById(Integer id) {
        if (id == null) {
            return null;
        }
        String sql = "SELECT * FROM tb_article WHERE id = ?";
        List<Article> articles = jdbcTemplate.query(sql,
                new BeanPropertyRowMapper<>(Article.class), id);
        return articles.isEmpty() ? null : articles.get(0);
    }

    @Override
    public List<Article> selectByConditionWithLimit(ArticleConditionDto articleCondition, Integer startIndex, Integer pageSize) {
        if (articleCondition == null || startIndex == null || pageSize == null) {
            return new ArrayList<>();
        }

        StringBuilder sql = new StringBuilder("SELECT * FROM tb_article WHERE 1=1");
        List<Object> params = new ArrayList<>();

        if (articleCondition.getUserId() != null) {
            sql.append(" AND user_id = ?");
            params.add(articleCondition.getUserId());
        }
        if (articleCondition.getTitle() != null && !articleCondition.getTitle().trim().isEmpty()) {
            sql.append(" AND title LIKE ?");
            params.add("%" + articleCondition.getTitle() + "%");
        }
        if (articleCondition.getContent() != null && !articleCondition.getContent().trim().isEmpty()) {
            sql.append(" AND content LIKE ?");
            params.add("%" + articleCondition.getContent() + "%");
        }
        if (articleCondition.getStatus() != null) {
            sql.append(" AND status = ?");
            params.add(articleCondition.getStatus());
        }
        if (articleCondition.getCategoryId() != null) {
            sql.append(" AND category_id = ?");
            params.add(articleCondition.getCategoryId());
        }

        sql.append(" ORDER BY create_time DESC LIMIT ?, ?");
        params.add(startIndex);
        params.add(pageSize);

        return jdbcTemplate.query(sql.toString(),
                new BeanPropertyRowMapper<>(Article.class), params.toArray());
    }

    @Override
    public int countByCondition(ArticleConditionDto articleCondition) {
        if (articleCondition == null) {
            String sql = "SELECT COUNT(*) FROM tb_article";
            return jdbcTemplate.queryForObject(sql, Integer.class);
        }

        StringBuilder sql = new StringBuilder("SELECT COUNT(*) FROM tb_article WHERE 1=1");
        List<Object> params = new ArrayList<>();

        if (articleCondition.getUserId() != null) {
            sql.append(" AND user_id = ?");
            params.add(articleCondition.getUserId());
        }
        if (articleCondition.getTitle() != null && !articleCondition.getTitle().trim().isEmpty()) {
            sql.append(" AND title LIKE ?");
            params.add("%" + articleCondition.getTitle() + "%");
        }
        if (articleCondition.getContent() != null && !articleCondition.getContent().trim().isEmpty()) {
            sql.append(" AND content LIKE ?");
            params.add("%" + articleCondition.getContent() + "%");
        }
        if (articleCondition.getStatus() != null) {
            sql.append(" AND status = ?");
            params.add(articleCondition.getStatus());
        }
        if (articleCondition.getCategoryId() != null) {
            sql.append(" AND category_id = ?");
            params.add(articleCondition.getCategoryId());
        }

        return params.isEmpty() ?
                jdbcTemplate.queryForObject(sql.toString(), Integer.class) :
                jdbcTemplate.queryForObject(sql.toString(), Integer.class, params.toArray());
    }
}